using System;
using System.Runtime.InteropServices;

using Pegasus.Windows.API.Enumerations;

namespace Pegasus.Windows.API.Interfaces
{
	/// <summary>
	/// Exposed by all Shell namespace folder objects. Its methods are used to manage folders.
	/// </summary>
	/// <remarks>
	/// This interface was implmented as part of the WindowsShell class and only the methods
	/// that it used have been documented and validated to make sure the marshalling parameters
	/// are correct.
	/// </remarks>
	[ComImport]
	[InterfaceType( ComInterfaceType.InterfaceIsIUnknown )]
	[Guid( "000214E6-0000-0000-C000-000000000046" )]
	public interface IShellFolder 
	{
		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="hwnd">The HWND.</param>
		/// <param name="pbc">The PBC.</param>
		/// <param name="pszDisplayName">Name of the PSZ display.</param>
		/// <param name="pchEaten">The PCH eaten.</param>
		/// <param name="ppidl">The ppidl.</param>
		/// <param name="pdwAttributes">The PDW attributes.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 ParseDisplayName( IntPtr hwnd, IntPtr pbc, [MarshalAs( UnmanagedType.LPWStr )] string pszDisplayName,
			ref uint pchEaten, out IntPtr ppidl, ref SFGAO pdwAttributes );

		/// <summary>
		/// Enables a client to determine the contents of a folder by creating an item identifier enumeration 
		/// object and returning its IEnumIDList interface. The methods supported by that interface can then be
		/// used to enumerate the folder's contents.
		/// </summary>
		/// <param name="hWnd">If user input is required to perform the enumeration, this window handle should 
		/// be used by the enumeration object as the parent window to take user input. An example would be a dialog 
		/// box to ask for a password or prompt the user to insert a CD or floppy disk. If hWnd is set to IntPtr.Zero, 
		/// the enumerator should not post any messages, and if user input is required, it should silently fail.</param>
		/// <param name="grfFlags">Flags indicating which items to include in the enumeration. For a list of possible 
		/// values, see the SHCONT enumerated type.</param>
		/// <returns>The reference to the IEnumIDList interface of the enumeration object created by this method. 
		/// If an error occurs or no suitable subobjects are found NULL is returned.</returns>
		IntPtr EnumObjects( IntPtr hWnd, SHCONTF grfFlags );


		/// <summary>
		/// Retrieves a handler, typically the Shell folder object that implements IShellFolder for a particular item. 
		/// Optional parameters that control the construction of the handler are passed in the bind context.
		/// </summary>
		/// <param name="pidl">The pidl.</param>
		/// <param name="bindContext">TODO: Setup IBindCtx interface, for now pass IntPtr.Zero.</param>
		/// <param name="riid">The IID of the interface being requested.</param>
		/// <returns></returns>
		IntPtr BindToObject( IntPtr pidl, IntPtr bindContext, Guid riid );

		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="pidl">The pidl.</param>
		/// <param name="pbc">The PBC.</param>
		/// <param name="riid">The riid.</param>
		/// <param name="ppv">The PPV.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 BindToStorage( IntPtr pidl, IntPtr pbc, ref Guid riid, out IntPtr ppv );

		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="lParam">The l param.</param>
		/// <param name="pidl1">The pidl1.</param>
		/// <param name="pidl2">The pidl2.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 CompareIDs( IntPtr lParam, IntPtr pidl1, IntPtr pidl2 );

		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="hwndOwner">The HWND owner.</param>
		/// <param name="riid">The riid.</param>
		/// <param name="ppv">The PPV.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 CreateViewObject( IntPtr hwndOwner, Guid riid, out IntPtr ppv );

		/// <summary>
		/// Gets the attributes of the child object.
		/// </summary>
		/// <param name="cidl">The cidl.</param>
		/// <param name="apidl">The apidl.</param>
		/// <param name="attributes">The attributes.</param>
		/// <returns></returns>
		uint GetAttributesOf( uint cidl, [MarshalAs( UnmanagedType.LPArray )] IntPtr[] apidl, ref SFGAO attributes );

		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="hwndOwner">The HWND owner.</param>
		/// <param name="cidl">The cidl.</param>
		/// <param name="apidl">The apidl.</param>
		/// <param name="riid">The riid.</param>
		/// <param name="rgfReserved">The RGF reserved.</param>
		/// <param name="ppv">The PPV.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 GetUIObjectOf( IntPtr hwndOwner, uint cidl, [MarshalAs( UnmanagedType.LPArray )] IntPtr[] apidl, ref Guid riid, IntPtr rgfReserved, out IntPtr ppv );

		/// <summary>
		/// Retrieves the display name for the specified file object or subfolder.
		/// </summary>
		/// <param name="pidl">Pointer to an item identifier list (PIDL) that uniquely identifies the file object or subfolder relative to the parent folder.</param>
		/// <param name="uFlags">Flags used to request the type of display name to return. For a list of possible values, see the SHGNO enumerated type.</param>
		/// <param name="strRet">When this method returns, contains a pointer to a STRRET structure in which to return the display name. The type of name returned in this structure can be the requested type, but the Shell folder might return a different type.</param>
		/// <returns>Returns WindowsConst.S_OK if successful, or an error value otherwise.</returns>
		[PreserveSig()]
		uint GetDisplayNameOf( IntPtr pidl, SHGNO uFlags, IntPtr strRet );

		/// <summary>
		/// Has not been validated.
		/// </summary>
		/// <param name="hwnd">The HWND.</param>
		/// <param name="pidl">The pidl.</param>
		/// <param name="pszName">Name of the PSZ.</param>
		/// <param name="uFlags">The u flags.</param>
		/// <param name="ppidlOut">The ppidl out.</param>
		/// <returns></returns>
		[PreserveSig]
		Int32 SetNameOf( IntPtr hwnd, IntPtr pidl, [MarshalAs( UnmanagedType.LPWStr )] string pszName, SHGNO uFlags, out IntPtr ppidlOut );
	}
}
